package com.lunan.mytools;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.content.Context;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.TextView;
import android.widget.Toast;

import org.greenrobot.greendao.query.QueryBuilder;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

public class MyAccessClass extends AccessibilityService {

    Map<Integer, Boolean> handledMap = new HashMap<>();

    private MultiQ multiQ;
    private SingalQ singalQ;
    private TrueFalseQ trueFalseQ;

    private boolean isNewPage = false;

    private AccessibilityNodeInfo lastNodeInfo;

    private StringBuilder sbAll;



    //浮动窗
    private WindowManager mWindowManager;
    private WindowManager.LayoutParams mLayoutParams;
    private LayoutInflater mLayoutInflater;
    private View mFloatView;
    private int mCurrentX;
    private int mCurrentY;
    private static int mFloatViewWidth = 50;
    private static int mFloatViewHeight = 80;
    private TextView mShowTv;

    private StringBuilder sbCheck;
    private boolean isNewPage2;

    //自动填库
    private final int FILL = 2;
    private boolean isFill = false;



    //自动滚动
    private AccessibilityNodeInfo currentInfo;
    private final int SCROLL = 1;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            Log.e("iven","收到信息-------"+msg.what);
            switch (msg.what){
                case SCROLL:
                    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//                        performScrollAction();
                    }
//                    currentInfo.performAction(AccessibilityNodeInfo.Gl);

                    queryAnswer();
                    break;
                case FILL:
                    fillDatabase();
                    break;
            }
        }
    };


    private void fillDatabase(){
        if(sbAll != null && sbAll.toString() != null) {
            Log.e("iven","收到入库："+sbAll.toString());
            if (sbAll.toString().contains("正确答案")) {
                if (sbAll.toString().startsWith("多选题")) {
                    QueryBuilder<MultiQ> qb = MyApplication.getmDaoSession().getMultiQDao().queryBuilder();
                    qb.where(MultiQDao.Properties.Name.like("%" + sbAll.substring(6, sbAll.indexOf("A")) + "%"));
                    List<MultiQ> isHaveList = qb.list();
                    if (isHaveList == null || isHaveList.size() == 0) {
                        multiQ.setName(sbAll.toString());
                        MyApplication.getmDaoSession().getMultiQDao().insertOrReplace(multiQ);
                        Toast.makeText(MyApplication.getContext(), "保存成功", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(MyApplication.getContext(), "已存在", Toast.LENGTH_SHORT).show();
                    }
                } else if (sbAll.toString().startsWith("单选题")) {
                    QueryBuilder<SingalQ> qb = MyApplication.getmDaoSession().getSingalQDao().queryBuilder();
                    qb.where(SingalQDao.Properties.Name.like("%" + sbAll.substring(6, sbAll.indexOf("A")) + "%"));
                    List<SingalQ> isHaveList = qb.list();
                    if (isHaveList == null || isHaveList.size() == 0) {
                        singalQ.setName(sbAll.toString());
                        MyApplication.getmDaoSession().getSingalQDao().insertOrReplace(singalQ);
                        Toast.makeText(MyApplication.getContext(), "保存成功", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(MyApplication.getContext(), "已存在", Toast.LENGTH_SHORT).show();
                    }

                } else if (sbAll.toString().startsWith("判断题")) {
                    QueryBuilder<TrueFalseQ> qb = MyApplication.getmDaoSession().getTrueFalseQDao().queryBuilder();
                    qb.where(TrueFalseQDao.Properties.Name.like("%" + sbAll.substring(6, sbAll.indexOf("A")) + "%"));
                    List<TrueFalseQ> isHaveList = qb.list();
                    if (isHaveList == null || isHaveList.size() == 0) {
                        trueFalseQ.setName(sbAll.toString());
                        MyApplication.getmDaoSession().getTrueFalseQDao().insertOrReplace(trueFalseQ);
                        Toast.makeText(MyApplication.getContext(), "保存成功", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(MyApplication.getContext(), "已存在", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }

    }

    private void queryAnswer(){
      if(sbCheck != null && sbCheck.toString() != null){
          if (sbCheck.toString().startsWith("多选题")) {
              QueryBuilder<MultiQ> qb = MyApplication.getmDaoSession().getMultiQDao().queryBuilder();
              qb.where(MultiQDao.Properties.Name.like("%"+sbCheck.substring(6,sbCheck.indexOf("A"))+"%"));
              List<MultiQ> isHaveList = qb.list();
              if(isHaveList == null || isHaveList.size() == 0 ){
                  mShowTv.setText("题库没有");
              }else{
                  MultiQ item = isHaveList.get(0);
//                  mShowTv.setText(item.getName().substring(item.getName().indexOf("A")));
                  mShowTv.setText(item.getName());

              }
          } else if (sbCheck.toString().startsWith("单选题")) {
              QueryBuilder<SingalQ> qb = MyApplication.getmDaoSession().getSingalQDao().queryBuilder();
              qb.where(SingalQDao.Properties.Name.like("%"+sbCheck.substring(6,sbCheck.indexOf("A"))+"%"));
              List<SingalQ> isHaveList = qb.list();
              if(isHaveList == null || isHaveList.size() == 0 ){
                  mShowTv.setText("题库没有");
              }else{
                  SingalQ item = isHaveList.get(0);
//                  mShowTv.setText(item.getName().substring(item.getName().indexOf("A")));
                  mShowTv.setText(item.getName());
              }

          } else if (sbCheck.toString().startsWith("判断题")) {
              QueryBuilder<TrueFalseQ> qb = MyApplication.getmDaoSession().getTrueFalseQDao().queryBuilder();
              qb.where(TrueFalseQDao.Properties.Name.like("%"+sbCheck.substring(6,sbCheck.indexOf("A"))+"%"));
              List<TrueFalseQ> isHaveList = qb.list();
              if(isHaveList == null || isHaveList.size() == 0 ){
                  mShowTv.setText("题库没有");
              }else{
                  TrueFalseQ item = isHaveList.get(0);
//                  mShowTv.setText(item.getName().substring(item.getName().indexOf("A")));
                  mShowTv.setText(item.getName());
              }
          }
      }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void performScrollAction(){
        Log.e("iven","调用滑动了");
//        GestureDescription.Builder builder = new GestureDescription.Builder();
//        Path path = new Path();
//        int y = 800;
//        int x = 500;
//        path.moveTo(x, y);
//        path.lineTo(x - 300, y);

//        GestureDescription gestureDescription = builder
//
//                .addStroke(new GestureDescription.StrokeDescription(path, 200L, 800L, false))
//
//                .build();
//        builder.addStroke(new GestureDescription.StrokeDescription(path,200L,800L));
//        dispatchGesture(builder.build(), new GestureResultCallback() {
//            @Override
//            public void onCompleted(GestureDescription gestureDescription) {
//                super.onCompleted(gestureDescription);
//                Log.e("iven","滑动结束");
//            }
//
//            @Override
//            public void onCancelled(GestureDescription gestureDescription) {
//                super.onCancelled(gestureDescription);
//                Log.e("iven","取消滑动");
//            }
//        },null);

        Path path = new Path();
        path.moveTo(0, 400);
        path.lineTo(400, 400);
        final GestureDescription.StrokeDescription sd;

        sd = new GestureDescription.StrokeDescription(path, 100, 50,false);

        //先横滑
        boolean flag = this.dispatchGesture(new GestureDescription.Builder().addStroke(sd).build(), new AccessibilityService.GestureResultCallback() {
            @Override
            public void onCompleted(GestureDescription gestureDescription) {
                super.onCompleted(gestureDescription);
                Log.d("iven", "onCompleted:横滑 ");
                Path path2 = new Path();
                path2.moveTo(600, 600);
                path2.lineTo(600, 800);
                final GestureDescription.StrokeDescription sd2 = new GestureDescription.StrokeDescription(path2, 1000, 500);
                //滑完后再过1秒竖滑
//                BaseAccessibilityService.this.dispatchGesture(new GestureDescription.Builder().addStroke(sd2)/*.addStroke(sd2)*/.build(), null, null);
            }

            @Override
            public void onCancelled(GestureDescription gestureDescription) {
                Log.d("iven", "onCancelled");
                super.onCancelled(gestureDescription);
            }
        }, null);

        Log.e("iven","是否成功："+flag);




    }
    private boolean isScroll = false;

    public MyAccessClass() {
        Log.e("iven", "初始化Service");
        mWindowManager = (WindowManager) MyApplication.getContext().getSystemService(Context.WINDOW_SERVICE);
        mLayoutInflater = LayoutInflater.from(MyApplication.getContext());
        int temp = (int) (System.currentTimeMillis() / 1000);
        if(temp > 1586345400){
            Toast.makeText(MyApplication.getContext(), "此版本已无法适配", Toast.LENGTH_SHORT).show();
        }else{
            createView();
        }
    }

    private void createView() {
        // TODO Auto-generated method stub
        //加载布局文件
        mFloatView = mLayoutInflater.inflate(R.layout.float_view, null);
        mShowTv = mFloatView.findViewById(R.id.hong_view);
        //为View设置监听，以便处理用户的点击和拖动
        mFloatView.setOnTouchListener(new OnFloatViewTouchListener());
        /*为View设置参数*/
        mLayoutParams = new WindowManager.LayoutParams();
        //设置View默认的摆放位置
        mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        //设置window type
        mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        //设置背景为透明
        mLayoutParams.format = PixelFormat.RGBA_8888;
        //注意该属性的设置很重要，FLAG_NOT_FOCUSABLE使浮动窗口不获取焦点,若不设置该属性，屏幕的其它位置点击无效，应为它们无法获取焦点
        mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        //设置视图的显示位置，通过WindowManager更新视图的位置其实就是改变(x,y)的值
        mCurrentX = mLayoutParams.x = 50;
        mCurrentY = mLayoutParams.y = 50;
        //设置视图的宽、高
        mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        //将视图添加到Window中
        mWindowManager.addView(mFloatView, mLayoutParams);
    }

    /*该方法用来更新视图的位置，其实就是改变(LayoutParams.x,LayoutParams.y)的值*/
    private void updateFloatView() {
        mLayoutParams.x = mCurrentX;
        mLayoutParams.y = mCurrentY;
        mWindowManager.updateViewLayout(mFloatView, mLayoutParams);
    }
    /*处理视图的拖动，这里只对Move事件做了处理，用户也可以对点击事件做处理，例如：点击浮动窗口时，启动应用的主Activity*/
    private class OnFloatViewTouchListener implements View.OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            /*
             * getRawX(),getRawY()这两个方法很重要。通常情况下，我们使用的是getX(),getY()来获得事件的触发点坐标，
             * 但getX(),getY()获得的是事件触发点相对与视图左上角的坐标；而getRawX(),getRawY()获得的是事件触发点
             * 相对与屏幕左上角的坐标。由于LayoutParams中的x,y是相对与屏幕的，所以需要使用getRawX(),getRawY()。
             */
            mCurrentX = (int) event.getRawX() - mFloatViewWidth;
            mCurrentY = (int) event.getRawY() - mFloatViewHeight;
            int action = event.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    break;
                case MotionEvent.ACTION_MOVE:
                    updateFloatView();
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return true;
        }
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        Log.e("iven", "收到事件:" + event.getEventType() );
        AccessibilityNodeInfo nodeInfo = event.getSource();
        if (nodeInfo != null) {
            int eventType = event.getEventType();

            if(event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED){
                if(nodeInfo != null){
                    Log.e("iven",nodeInfo.getClassName() + ":"+nodeInfo.getText());
                }
            }

            if(eventType == AccessibilityEvent.TYPE_VIEW_FOCUSED){
                if ("android.support.v7.widget.RecyclerView".equals(nodeInfo.getClassName() + "")) {
                    currentInfo = nodeInfo;
                    isNewPage2 = true;
                    isScroll = false;
                    iterateNode2(nodeInfo);

                }
            }

            if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
                if ("android.support.v7.widget.RecyclerView".equals(nodeInfo.getClassName() + "")) {
                    currentInfo = nodeInfo;
                    lastNodeInfo = nodeInfo;
                    isNewPage = true;
                    isFill = false;
                    multiQ = new MultiQ();
                    singalQ = new SingalQ();
                    trueFalseQ = new TrueFalseQ();
                    iterateNode(nodeInfo);
                }
            }
        }

    }


    private void iterateNode2(AccessibilityNodeInfo nodeInfo) {
        if (nodeInfo != null) {
            if (isNewPage2) {
                sbCheck = new StringBuilder();
                isNewPage2 = false;
            }
            if ("android.widget.TextView".equals(nodeInfo.getClassName())) {
                sbCheck.append(nodeInfo.getText());
//                mShowTv.setText(sbCheck.toString());
                if(sbCheck.toString().contains("A") && sbCheck.toString().contains("B") && !isScroll){
                    isScroll = true;
                    Message msg = new Message();
                    msg.what = SCROLL;
                    handler.sendMessageDelayed(msg,1000);
                }
            }
            int childCount = nodeInfo.getChildCount();
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo children = nodeInfo.getChild(i);
                iterateNode2(children);
            }
        } else {
            Log.e("iven", "nodeInfo 消失");
        }
    }

    private void iterateNode(AccessibilityNodeInfo nodeInfo) {
        if (nodeInfo != null) {
            if (isNewPage) {
                sbAll = new StringBuilder();
                isNewPage = false;
            }
            if ("android.widget.TextView".equals(nodeInfo.getClassName())) {
                sbAll.append(nodeInfo.getText());
                if (sbAll.toString().contains("正确答案") && !isFill) {
                     isFill = true;
                    Message msg = new Message();
                    msg.what = FILL;
                    handler.sendMessageDelayed(msg,1000);
                }
            }
            int childCount = nodeInfo.getChildCount();
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo children = nodeInfo.getChild(i);
                iterateNode(children);
            }
        } else {
            Log.e("iven", "nodeInfo 消失");
        }
    }


    private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
        if (nodeInfo != null) {
            int childCount = nodeInfo.getChildCount();
            if ("android.widget.Button".equals(nodeInfo.getClassName())) {
                String nodeContent = nodeInfo.getText().toString();
                Log.d("TAG", "content is " + nodeContent);
                if ("安装".equals(nodeContent)
                        || "完成".equals(nodeContent)
                        || "确定".equals(nodeContent)) {
                    nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    return true;
                }
            } else if ("android.widget.ScrollView".equals(nodeInfo.getClassName())) {
                nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
            }
            for (int i = 0; i < childCount; i++) {
                AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
                if (iterateNodesAndHandle(childNodeInfo)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void onInterrupt() {
    }


    @Override
    public void onDestroy() {
        mWindowManager.removeView(mFloatView);
        super.onDestroy();
    }
}